home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
302_01
/
ac.c
< prev
next >
Wrap
Text File
|
1990-02-14
|
5KB
|
139 lines
/* Add corner to face
Copyright (c) 1988 by Gus O'Donnell
Revision history:
Version 1.00 February 29, 1988 As released.
Version 1.01 March 20, 1988 Created libraries for all
memory models
*/
#include <3d.h>
#include <alloc.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
int add_corner (double x, double y, double z, FACE *this_face)
/* Add a corner to a face. The initial data structure looks like this:
FACE X o----->CORNER o X
|
+---+
|
V
CORNER X X
Where 'X' is the NULL pointer. The revised structure looks like this:
FACE X o----->CORNER o X
|
+---+
|
V
CORNER X o----->VERTEX X
|
+---+
|
V
CORNER X X
Note that the corner is added to the beginning of the list. The corners
are assumed to be added in "standard" order, that is, counterclockwise
as the face is viewed from the outside of the object.
The new corner is checked for colinearity with the first two corners.
If it is colinear, it replaces the current first corner. The test
proceeds as follows:
Calculate the parametric representation of the line formed by the
first two corners:
X = A + t(B - A) (1)
where X is any point on the line, A and B are two points on the line
(the first two corners of the face), and t is the parameter. Thus:
X[0] = A[0] + t(B[0] - A[0]),
X[1] = A[1] + t(B[1] - A[1]),
X[2] = A[2] + t(B[2] - A[2]), (2)
Substitute the new corner's coordinates into the parametric equations
and calculate t for any dimension i such that A[i] != B[i]:
t = (C[i] - A[i])/(B[i] - A[i]) (3)
If all equations (2) are satisfied with this value of t, the points are
colinear.
The value returned is the status:
0 - success.
1 - memory allocation failed.
2 - corner is colinear, replaced first
corner with new corner.
*/
{
int count;
CORNER *chandle; /* Handle for new corner */
VERTEX *vhandle; /* Handle for new vertex */
VECTOR A,B,X; /* Temporary storage for colinearity check */
double t; /* Line parameter */
/* Test for colinearity */
chandle = this_face -> first -> next;
if ((chandle -> next) != NULL) /* At least 1 corner */
{
for (count = 0; count < DIM; count++)
A [count] = chandle -> this -> coord [count]; /* Get 1st corner */
chandle = chandle -> next;
if ((chandle -> next) != NULL) /* Face has 2 corners */
{
t = 0.0;
X[0] = x;
X[1] = y;
X[2] = z;
for (count = 0; count < DIM; count++)
{
B [count] = chandle -> this -> coord [count]; /* 2nd corner */
if (A[count] != B[count])
t = (X[count] - A[count])/(B[count] - A[count]);
count = DIM; /* Out of loop */
}
if ((X[0] == A[0] + t*(B[0] - A[0]))
&& (X[1] == A[1] + t*(B[1] - A[1]))
&& (X[2] == A[2] + t*(B[2] - A[2]))) /* Point is colinear */
{
chandle = this_face -> first -> next;
for (count = 0; count < DIM; count++)
/* Assign new coordinates */
/* to existing 1st corner */
chandle -> this -> coord [count] = X[count];
return (2); /* and return status */
}
}
}
/* If point is not colinear, get memory. Return a 1 if unsuccessful. */
if (!(chandle = (CORNER *)malloc(sizeof(CORNER)))) return(1);
if (!(vhandle = (VERTEX *)malloc(sizeof(VERTEX)))) return(1);
chandle -> next = this_face -> first -> next;
this_face -> first -> next = chandle;
chandle -> this = vhandle;
vhandle -> coord [0] = x;
vhandle -> coord [1] = y;
vhandle -> coord [2] = z;
vhandle -> next = NULL;
return(0);
}